package compilers.AST.basics;

import java.io.PrintStream;
import java.util.Iterator;
import java.util.LinkedList;

import compilers.AST.Node;
import compilers.AST.statement.ArrayDeclarationStatement;
import compilers.AST.statement.Statement;
import compilers.AST.statement.VariableDeclarationStatement;
import compilers.compiler.PGenerator;
import compilers.exceptions.SemanticalException;
import compilers.symbolTable.SymbolTable;
import compilers.symbolTable.SymbolTableElement;
import compilers.symbolTable.SymbolTableScope;
import compilers.symbolTable.SymbolTableVariableElement;

public class Program extends Node {
	
	private LinkedList<Statement> fStatements;

	public Program() {
		fStatements = new LinkedList<Statement>();
	}
	
	public Program(int lineNr) {
		super(lineNr);
		fStatements = new LinkedList<Statement>();
	}
	
	public void print(int identLevel) {
		println(identLevel, "Program");
		Iterator<Statement> it = fStatements.iterator();
		while (it.hasNext()) {
			it.next().print(identLevel+1);
		}
	}
	
	public void checkSemantics(SymbolTableScope currentScope) throws SemanticalException {
		// Check whether there is at least one statement
		if (fStatements.isEmpty()) {
			throw new SemanticalException("There should be at least one statement in the program.", getLine());
		}

		// Check statements
		Iterator<Statement> it = fStatements.iterator();
		Node temp = null;		
		while (it.hasNext()) {
			temp = it.next();
			temp.checkSemantics(currentScope);
		}
		
		// Check whether there is a main function
		if (currentScope.getElement("main", temp.getNodeId()) == null) {
			throw new SemanticalException("There should be a main function.", getLine());
		}
	}
	
	public void addStatement(Statement statement) {
		fStatements.add(statement);
	}
	
	public void generatePcode(PGenerator pGen, SymbolTableScope currentScope) {
		
		// Go to main function
		pGen.goToStart();
		
		// Generate code
		Iterator<Statement> it = fStatements.iterator();
		while (it.hasNext()) {
			it.next().generatePcode(pGen, currentScope);
		}
	}
	
	
}
